<?php
/**
 * Bdat Site development
 * @author Will Skates
 */

/*----------------------------------------------------------------------------------------------------*/

/**
 * Outline of properties and functionality required to make and use content in the system which is used 
 * to populate masonry blocks.
 * @author Will Skates
 *
 */
class BlockModel extends CI_Model {
	
	public $uid;
	public $title;
	public $content;
	public $timestamp;
	public $author;
	public $sticky;
	public $ctable;
	
	/**
	 * Construct an sql query to get the data for this content type from the database.
	 * @return	String		- The query.
	 */
	public function getQuery(  )
	{
		return 'SELECT ' . $this->ctable . '.uid,
						title,
						content,
						user_profiles.name,
						user_profiles.link,
						gradyears.date AS gradyear,
						sticky FROM ' . $this->ctable . ' 
				LEFT JOIN user_profiles ON user_profiles.userid = ' . $this->ctable . '.author
				LEFT JOIN gradyears ON gradyears.uid = user_profiles.gradyear
				WHERE published = 1';
	}
	
	/*----------------------------------------------------------------------------------------------------*/

	/**
	 * Get all data from the database for content of this type.
	 * @return	Array	- Array containing all of the content for this item.
	 */
	public function getAll()
	{
	
		$query = $this->db->query($this->getQuery( $this->ctable ));
		
		$res = $query->result();
		
		foreach($res as $k=>$v) {
			
			//Produce a version of the content for each item that has beeen shortned and also give it a string which contains it's identification data.
			$res[$k]->short 	= mb_substr(strip_tags(html_entity_decode($v->content,ENT_QUOTES)),0,120) . '...';
			$res[$k]->listNum 	= $k; 
			$res[$k]->ajaxString= urlencode(base64_encode(json_encode(array('title'=>$v->title, 'uid'=>$v->uid,'table'=>$this->ctable))));
		}
		
		return $query->result();
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Get a specific piece of content accordiong to its unique identification number.
	 * @param 	Integer		$id	- The unique identifier.
	 */
	public function getFromID($id)
	{
		
		$query = $this->db->query($this->getQuery( $this->ctable ) . ' AND ' . $this->ctable . '.uid=?', array($id));
		
		$res = $query->result();
		
		foreach($res as $k=>$v) {
			//Produce a version of the content for each item that has beeen shortned and also give it a string which contains it's identification data.
			$res[$k]->short 	= mb_substr(strip_tags(html_entity_decode($v->content,ENT_QUOTES)),0,120) . '...';
			$res[$k]->listNum 	= $k; 
			$res[$k]->ajaxString= urlencode(base64_encode(json_encode(array('title'=>$v->title, 'uid'=>$v->uid,'table'=>$this->ctable))));
		}
		
		return $query->result();
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Get a specific piece of content accordiong to its unique identification number regardless as to whether it has been published or not.
	 * @param 	Integer		$id	- The unique identifier.
	 */
	public function getAnyFromID($id)
	{
		
		$query = $this->db->query( str_replace('WHERE published = 1', '',$this->getQuery( $this->ctable )) . ' WHERE ' . $this->ctable . '.uid=?', array($id));
		
		$res = $query->result();
		
		foreach($res as $k=>$v) {
			
			//Produce a version of the content for each item that has beeen shortned and also give it a string which contains it's identification data.
			$res[$k]->short 	= mb_substr(strip_tags(html_entity_decode($v->content,ENT_QUOTES)),0,120) . '...';
			$res[$k]->listNum 	= $k; 
			$res[$k]->ajaxString= urlencode(base64_encode(json_encode(array('title'=>$v->title, 'uid'=>$v->uid,'table'=>$this->ctable))));
		}
		
		return $query->result();
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Use this object's data to create a new database record.
	 */
	public function insert()
	{
		$obj = clone($this);
		unset($obj->ctable);
		return $this->db->insert($this->ctable, $obj);
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Get the information as to the composition of the database table for this content type.
	 */
	public function describe()
	{
		$fields = array_keys((Array)$this);
		$sql = 'DESCRIBE ' . $this->ctable;
		$result = $this->db->query($sql)->result();
		foreach ( $result as $k=>$v ) {
			
			//We don't need information about the image associated with this post because that is only handled when a post is aggregated, not all of the time.
			if ($v->Field == 'image' || $v->Field == 'imageExtension') {
				unset($result[$k]);
			}
		}
		
		return $result;
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Use the structure of the dtabase table to create an array which we can use to construct a form in the cms.
	 */
	public function parseStructureForForm()
	{
		
		$fields = $this->describe();
		$parsed = array();
		
		$conversion = array(
			'int'=>'number',
			'tinyint'=>'number',
			'bigint'=>'number',
			'text'=>'longtext',
			'longtext'=>'longtext',
			'mediumtext'=>'longtext',
			'tinytext'=>'text',
			'varchar'=>'text',
			'char'=>'text',
			'date'=>'date',
			'bool'=>'boolean'
		);
		
		foreach ( $fields as $k => $v ) {
			
			$hasLength = false;
			
			if ( $v->Type == 'tinyint(1)' ) {
				
				//All tinyint(1) fields are used to dicate true/false values (0/1).
				$parsed[$k]->Type = 'bool';
				
			} else if(stripos($v->Type,'(')) {
				
				//Anything else with a length (i.e. varchar(255)) has a length associated with it, we just need the type here.
				$parsed[$k]->Type = reset(explode('(',$v->Type));
				$hasLength = true;
				
			} else {
				
				//Otherwise just use the type string to dictate what the type is.
				$parsed[$k]->Type = $v->Type;
			}
			
			if ( $hasLength ) {
				
				//If it has a length, then just get the length.
				$parsed[$k]->length = (int)str_replace(array($parsed[$k]->Type,'(',')'),'',$v->Type);
				
			} else {
				
				//Otherwise it can be anylength.
				$parsed[$k]->length = 'max';
				
			}
			
			//Replace the type string with the form friendly data type (all of these listed above in $conversion.
			$parsed[$k]->Type = $conversion[$parsed[$k]->Type];
			
			//Use the Null value on the database table to dictate whether the field can or can't be null (and thus whether it is required).
			$parsed[$k]->required = ($v->Null == 'NO') ? false:true;
			
			//Use the field name to dictate the name of the form field.
			$parsed[$k]->name = $v->Field;
			
			//First, assume that all columns are not keys, then check whether they are.
			$parsed[$k]->Key = false;
			
			if ( $v->Key == 'PRI' ) {
				
				//If the current table column is the primary key, note this.
				$parsed[$k]->Key = 'primary';
				
			} else if (
				substr($v->Field,  -2) == 'id' && $k != 0 ||
				substr($v->Field,  -2) == 'ID' && $k != 0
			) {
				
				//Otherwise, if it's the id field of a different table, not this, then lable it as a foreign key.
				$parsed[$k]->Key = 'foreign';
			}
			
			//Make sure that the field get's parsed as astdClass object (other methods will assume that this is the case as it's the data type that comes out of the db).
			$parsed[$k] = (Object)$parsed[$k];

		}
		
		return $parsed;
		
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Get all of the names of the fields that are in the table for this content type.
	 */
	public function getParsedFields()
	{
		$fields = $this->parseStructureForForm();
		$list = array();
		
		foreach ( $fields as $k=>$v ) {
			$list[] = $v->name;
		}
		
		return $list;
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Get the data for a record to be put into a form.
	 * @param	Integer		$id - The unique identifier for a particular item.
	 */
	public function getForForm($id)
	{
		
		$sql = 'SELECT ' . implode(',',$this->getParsedFields()) . ' FROM ' . $this->ctable . ' WHERE uid=?';
		$result = $this->db->query($sql,array($id))->result();
		
		if ( count($result) > 0 ) {
			return $result;
		} else {
			return false;
		}
	} 
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Make a block model object for a given piece of content.
	 * @param	Integer		$id - The unique identifier for a particular item.
	 */
	public function makeFromID($id)
	{
		
		//Get the data for this particular item.
		$list = $this->getAnyFromID($id);
		
		//Make sure that there is any data associated with that unique identifier.
		if ( count($list) > 0 ) { 
			$res = (Array)$list[0]; 
		} else { 
			return false; 
		}
		
		//Then make a new object for that piece of content and give it the data associated with this particular unique identifier.
		$obj = clone($this);
		foreach ( $res as $k=>$v ) {
			$obj->$k = $v;
		}
		
		return $obj;
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * Functionality that get's run automatically when the cms saves an item (by default this does nothing as this changes from content-type to content-type.
	 */
	public function saveCallback(){}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	
}